home *** CD-ROM | disk | FTP | other *** search
/ LiquidLibrary 2005 September / LiquidLibrary 2005 Sep - Disc 1.iso / pc / Portfolio Browser / Filters / PDF / pstotxt3.dll / RCDATA / 1 next >
Text File  |  2003-01-03  |  27KB  |  738 lines

  1. % Copyright (C) 1995, Digital Equipment Corporation.
  2. % All rights reserved.
  3. % See the file pstotext.txt for a full description.
  4.  
  5. % ocr.ps, part of BuildLectern
  6. %
  7. %   This is a PostScript library to send the characters rendered by a
  8. %   PostScript job back on stdout.  The output is intended to allow
  9. %   reconstruction of the document's words and an approximation of the words'
  10. %   bounding rectangles.
  11.  
  12. % Last modified on Sat Feb  5 21:00:00 AEST 2000 by rjl
  13. %      modified on Fri Oct  2 17:13:53 PDT 1998 by mcjones
  14. %      modified on Thu Jan 25 15:24:37 PST 1996 by deutsch
  15. %      modified on Wed May  3 15:41:30 PDT 1995 by birrell
  16.  
  17. % Restrictions:
  18. %
  19. %   This library redefines some names that are originally defined as
  20. %   operators, and of course the new definitions are procedures. Some
  21. %   jobs might be sensitive to this distinction.  In this case, you'd
  22. %   need to make "redef" create a new operator.  For example, "odef".
  23. %
  24. %   This library reports characters rendered by show, ashow, showwidth,
  25. %   ashowwidth and kshow.  The characters are reported even if they would
  26. %   be invisible in final hardcopy.  This could happen, for example, if the
  27. %   characters get clipped, or if they get overprinted, or if they are the
  28. %   same color as their background, or if the font's glyph make no marks.
  29. %
  30. %   PostScript doesn't specify a standard character code for the characters
  31. %   being rendered; rather, the font maps small integers into glyphs.  It's
  32. %   not possible in general to determine a translation back into a standard
  33. %   character code.  This library approximates this by giving mappings from
  34. %   the job's characters to indexes into a table of known glyph names.  This
  35. %   handles most PostScript jobs that we've encountered, but it's not an
  36. %   absolute solution to the problem.
  37.  
  38. % Output format:
  39. %
  40. %    The "reporting coordinate system" is the device coordinate system.  The
  41. %    application interpreting this library's output needs to understand the
  42. %    device coordinate system.
  43. %
  44. %    Positions are reported in the reporting coordinate system, but with (x,y) 
  45. %    values multiplied by 100 and rounded to integers.  Note that
  46. %    positions might involve negative integers.
  47. %
  48. %    The directives, whitespace and numbers are themselves encoded in ASCII.
  49. %    The strings in the "S" directives are in currentfont's encoding: they
  50. %    should be treated as 8-bit binary data.
  51. %
  52. %    QI 6-integers
  53. %                       Specifies the inverse of the currentmatrix for
  54. %                       the current output device, after rotXXX.ps and
  55. %                       before the document is processed.
  56. %
  57. %    QM m blx bly trx try 256-pairs
  58. %                    Introduces a new character metrics table used by
  59. %                    some font, where "m" is an integer that identifies
  60. %                    the metrics table in subsequent "F" directives.  "m"
  61. %                    is small.  (blx,bly) is the bottom left corner of the
  62. %                    font's bounding box, and (trx,try) is its top right. 
  63. %                    The pairs are the stringwidth of each character in the
  64. %                    font's encoding.  All of these are reported in the
  65. %                    font's character coordinate system, multiplied by 100
  66. %                    and rounded to integers.  The metrics
  67. %                    table will be referenced in a subsequent "F"
  68. %                    directive, which includes information mapping the
  69. %                    font's metrics to the initial user coordinate system. 
  70. %                    Note that values of "m" might get reused, after a
  71. %                    "restore".
  72. %
  73. % QE e n n-integers  Introduces a new encoding, where "e" is an integer
  74. %                    that identifies the encoding in subsequent "F"
  75. %                    directives.  "e" is small.  "e" is followed by
  76. %                    an integer "n" and then by a sequence of
  77. %                    exactly n integers.  The i'th integer
  78. %                    specifies the glyph for the i'th entry of the
  79. %                    font's encoding vector.  The value of the
  80. %                    integer is usually an index in the array
  81. %                    "StandardGlyphs", defined below.  Note that
  82. %                    the first 256 entries of that array equal the
  83. %                    corresponding entries of ISOLatin1Encoding.
  84. %                    The value 9999 indicates that this entry in
  85. %                    the font's encoding specifies a glyph not
  86. %                    named in StandardGlyphs.  Note that values of
  87. %                    "e" might get reused, after a "restore".
  88. %
  89. %    QF n x y x' y' e m      Introduces a new font, where "n" is an integer
  90. %                    that identifies the font in subsequent "S"
  91. %                    directives.  "n" is small.  (x,y) is the
  92. %                    position corresponding to (1000,0) in the font's
  93. %                    character coordinate system, and (x',y') is the
  94. %                    position corresponding to (0,1000), both as they would
  95. %                    be if the character were drawn with its origin at
  96. %                    the origin of the reporting coordinate system. "e" is
  97. %                    an integer specifying a previously defined
  98. %                    encoding vector.  "m" is an integer specifying a
  99. %                    previously defined metrics table.  Note that values
  100. %                    of "n" might get reused, after a "restore".
  101. %
  102. %    QS n x y l s x' y'      Reports rendering of string "s" in font "n".
  103. %                    (x,y) is the position corresponding to the origin of
  104. %                    the first character. "l" is length of the string,
  105. %                    followed immediately by a single space then the string.
  106. %                    (x',y') is the position that would correspond to the
  107. %                    origin of a subsequent character. The
  108. %                    string reported by this directive is never empty.
  109. %                    The string also never contains a "space": strings
  110. %                    that would have contained a "space" are split up
  111. %                    into multiple directives, with the "space"
  112. %                    omitted.  Here "space" means the first character
  113. %                    in the font's encoding that maps to the glyph
  114. %                    named "/space", if there is such a character.
  115. %
  116. %    QC                      copypage was invoked
  117. %
  118. %    QZ                      erasepage was invoked
  119. %
  120. %    QP                      showpage was invoked
  121.  
  122. %
  123. % globals and subroutines
  124. %
  125.  
  126. %/setglobal where
  127. % { pop currentglobal /setglobal load true setglobal }
  128. % { { } }
  129. %ifelse
  130. revision 353 ge {
  131. NOBIND /DELAYBIND where { pop DELAYBIND or } if
  132.  { systemdict begin
  133.                 /bind /.bind load
  134.                   /.forcedef where { pop .forcedef } { def } ifelse
  135.               end
  136.  }
  137. if
  138. } if
  139.  
  140. % put our private stuff in a local dictionary,
  141. % but place a reference to it in systemdict
  142. systemdict begin
  143. /pstotextLocalDict 30 dict /.forcedef where { pop .forcedef } { def } ifelse
  144. end
  145.  
  146. pstotextLocalDict begin              % following stuff is private
  147. /redef { systemdict begin 1 index exch .makeoperator def end } bind def
  148. /privateDict currentdict def % for lastFontNum and lastEncoding
  149. /fonts 200 dict def          % maps font to integer "n"
  150. /fontsUnit 200 dict def      % (1000,0) and (0,1000) transformed, per font
  151. /encodings 200 dict def              % maps encoding array to integer "e"
  152. /encodingSpace 200 dict def  % space char for each encoding
  153. /metrics 200 dict def                % maps font UniqueID to integer  "m"
  154. /lastFontNum 0 def           % last integer used for a font
  155. /lastEncoding 0 def          % last integer used for an encoding
  156. /lastMetrics 0 def           % last integer used for a metrics table
  157. /tempString 20 string def    % scratch for printing integers
  158. /reportMatrix matrix identmatrix def % maps device coords to reporting coords
  159. /inUse false def             % prevents recursive invokcation of "report"
  160.  
  161. /TimesRomanGlyphs [
  162.   % ISOLatin1Encoding ...
  163.   /.notdef /.notdef /.notdef /.notdef /.notdef
  164.   /.notdef /.notdef /.notdef /.notdef /.notdef
  165.   /.notdef /.notdef /.notdef /.notdef /.notdef
  166.   /.notdef /.notdef /.notdef /.notdef /.notdef
  167.   /.notdef /.notdef /.notdef /.notdef /.notdef
  168.   /.notdef /.notdef /.notdef /.notdef /.notdef
  169.   /.notdef /.notdef /space /exclam /quotedbl
  170.   /numbersign /dollar /percent /ampersand /quoteright
  171.   /parenleft /parenright /asterisk /plus /comma
  172.   /minus /period /slash /zero /one
  173.   % 50
  174.   /two /three /four /five /six
  175.   /seven /eight /nine /colon /semicolon
  176.   /less /equal /greater /question /at
  177.   /A /B /C /D /E
  178.   /F /G /H /I /J
  179.   /K /L /M /N /O
  180.   /P /Q /R /S /T
  181.   /U /V /W /X /Y
  182.   /Z /bracketleft /backslash /bracketright /asciicircum
  183.   /underscore /quoteleft /a /b /c
  184.   % 100
  185.   /d /e /f /g /h
  186.   /i /j /k /l /m
  187.   /n /o /p /q /r
  188.   /s /t /u /v /w
  189.   /x /y /z /braceleft /bar
  190.   /braceright /asciitilde /.notdef /.notdef /.notdef
  191.   /.notdef /.notdef /.notdef /.notdef /.notdef
  192.   /.notdef /.notdef /.notdef /.notdef /.notdef
  193.   /.notdef /.notdef /.notdef /.notdef /dotlessi
  194.   /grave /acute /circumflex /tilde /macron
  195.   % 150
  196.   /breve /dotaccent /dieresis /.notdef /ring
  197.   /cedilla /.notdef /hungarumlaut /ogonek /caron
  198.   /space /exclamdown /cent /sterling /currency
  199.   /yen /brokenbar /section /dieresis /copyright
  200.   /ordfeminine /guillemotleft /logicalnot /hyphen /registered
  201.   /macron /degree /plusminus /twosuperior /threesuperior
  202.   /acute /mu /paragraph /periodcentered /cedilla
  203.   /onesuperior /ordmasculine /guillemotright /onequarter /onehalf
  204.   /threequarters /questiondown /Agrave /Aacute /Acircumflex
  205.   /Atilde /Adieresis /Aring /AE /Ccedilla
  206.   % 200
  207.   /Egrave /Eacute /Ecircumflex /Edieresis /Igrave
  208.   /Iacute /Icircumflex /Idieresis /Eth /Ntilde
  209.   /Ograve /Oacute /Ocircumflex /Otilde /Odieresis
  210.   /multiply /Oslash /Ugrave /Uacute /Ucircumflex
  211.   /Udieresis /Yacute /Thorn /germandbls /agrave
  212.   /aacute /acircumflex /atilde /adieresis /aring
  213.   /ae /ccedilla /egrave /eacute /ecircumflex
  214.   /edieresis /igrave /iacute /icircumflex /idieresis
  215.   /eth /ntilde /ograve /oacute /ocircumflex
  216.   /otilde /odieresis /divide /oslash /ugrave
  217.   % 250
  218.   /uacute /ucircumflex /udieresis /yacute /thorn
  219.   /ydieresis 
  220.   % Other glyphs from /Times-Roman ...
  221.   % 256
  222.   /quotedblright /Scaron /dagger /guilsinglleft
  223.   /Zcaron /daggerdbl /Lslash /ellipsis /guilsinglright
  224.   /oe /fi /bullet /perthousand /quotedblbase
  225.   /endash /emdash /trademark /florin /lslash
  226.   /scaron /Ydieresis /fl /fraction /quotedblleft
  227.   /quotesinglbase /quotesingle /zcaron /OE
  228.   % 284
  229.   ] def
  230.  
  231. /dvipsGlyphs [
  232.   % Self-named glyphs for dvitops type 3 fonts ...
  233.   % 284
  234.   0 1 255 { 1 string dup 0 4 -1 roll put cvn } for
  235.   % 540
  236.   ] def
  237.  
  238. /ttypeGlyphs1 [
  239.   % Glyph names used by MS TrueType encodings ...
  240.   % 540
  241.   /G00 /G01 /G02 /G03 /G04 /G05 /G06 /G07 /G08 /G09 /G0a /G0b /G0c /G0d /G0e
  242.   /G0f /G10 /G11 /G12 /G13 /G14 /G15 /G16 /G17 /G18 /G19 /G1a /G1b /G1c /G1d
  243.   /G1e /G1f /G20 /G21 /G22 /G23 /G24 /G25 /G26 /G27 /G28 /G29 /G2a /G2b /G2c
  244.   /G2d /G2e /G2f /G30 /G31 /G32 /G33 /G34 /G35 /G36 /G37 /G38 /G39 /G3a /G3b
  245.   % 600
  246.   /G3c /G3d /G3e /G3f /G40 /G41 /G42 /G43 /G44 /G45 /G46 /G47 /G48 /G49 /G4a
  247.   /G4b /G4c /G4d /G4e /G4f /G50 /G51 /G52 /G53 /G54 /G55 /G56 /G57 /G58 /G59
  248.   /G5a /G5b /G5c /G5d /G5e /G5f /G60 /G61 /G62 /G63 /G64 /G65 /G66 /G67 /G68
  249.   /G69 /G6a /G6b /G6c /G6d /G6e /G6f /G70 /G71 /G72 /G73 /G74 /G75 /G76 /G77
  250.   /G78 /G79 /G7a /G7b /G7c /G7d /G7e /G7f /G80 /G81 /G82 /G83 /G84 /G85 /G86
  251.   /G87 /G88 /G89 /G8a /G8b /G8c /G8d /G8e /G8f /G90 /G91 /G92 /G93 /G94 /G95
  252.   /G96 /G97 /G98 /G99 /G9a /G9b /G9c /G9d /G9e /G9f /Ga0 /Ga1 /Ga2 /Ga3 /Ga4
  253.   /Ga5 /Ga6 /Ga7 /Ga8 /Ga9 /Gaa /Gab /Gac /Gad /Gae /Gaf /Gb0 /Gb1 /Gb2 /Gb3
  254.   /Gb4 /Gb5 /Gb6 /Gb7 /Gb8 /Gb9 /Gba /Gbb /Gbc /Gbd /Gbe /Gbf /Gc0 /Gc1 /Gc2
  255.   /Gc3 /Gc4 /Gc5 /Gc6 /Gc7 /Gc8 /Gc9 /Gca /Gcb /Gcc /Gcd /Gce /Gcf /Gd0 /Gd1
  256.   % 750
  257.   /Gd2 /Gd3 /Gd4 /Gd5 /Gd6 /Gd7 /Gd8 /Gd9 /Gda /Gdb /Gdc /Gdd /Gde /Gdf /Ge0
  258.   /Ge1 /Ge2 /Ge3 /Ge4 /Ge5 /Ge6 /Ge7 /Ge8 /Ge9 /Gea /Geb /Gec /Ged /Gee /Gef
  259.   /Gf0 /Gf1 /Gf2 /Gf3 /Gf4 /Gf5 /Gf6 /Gf7 /Gf8 /Gf9 /Gfa /Gfb /Gfc /Gfd /Gfe
  260.   /Gff 
  261.   % 796
  262.   ] def
  263.  
  264. /ttypeGlyphs2 [
  265.   % 796
  266.   /G00 /G01 /G02 /G03 /G04 /G05 /G06 /G07 /G08 /G09 /G0A /G0B /G0C /G0D
  267.   /G0E /G0F /G10 /G11 /G12 /G13 /G14 /G15 /G16 /G17 /G18 /G19 /G1A /G1B /G1C
  268.   /G1D /G1E /G1F /G20 /G21 /G22 /G23 /G24 /G25 /G26 /G27 /G28 /G29 /G2A /G2B
  269.   /G2C /G2D /G2E /G2F /G30 /G31 /G32 /G33 /G34 /G35 /G36 /G37 /G38 /G39 /G3A
  270.   /G3B /G3C /G3D /G3E /G3F /G40 /G41 /G42 /G43 /G44 /G45 /G46 /G47 /G48 /G49
  271.   /G4A /G4B /G4C /G4D /G4E /G4F /G50 /G51 /G52 /G53 /G54 /G55 /G56 /G57 /G58
  272.   /G59 /G5A /G5B /G5C /G5D /G5E /G5F /G60 /G61 /G62 /G63 /G64 /G65 /G66 /G67
  273.   % 900
  274.   /G68 /G69 /G6A /G6B /G6C /G6D /G6E /G6F /G70 /G71 /G72 /G73 /G74 /G75 /G76
  275.   /G77 /G78 /G79 /G7A /G7B /G7C /G7D /G7E /G7F /G80 /G81 /G82 /G83 /G84 /G85
  276.   /G86 /G87 /G88 /G89 /G8A /G8B /G8C /G8D /G8E /G8F /G90 /G91 /G92 /G93 /G94
  277.   /G95 /G96 /G97 /G98 /G99 /G9A /G9B /G9C /G9D /G9E /G9F /GA0 /GA1 /GA2 /GA3
  278.   /GA4 /GA5 /GA6 /GA7 /GA8 /GA9 /GAA /GAB /GAC /GAD /GAE /GAF /GB0 /GB1 /GB2
  279.   /GB3 /GB4 /GB5 /GB6 /GB7 /GB8 /GB9 /GBA /GBB /GBC /GBD /GBE /GBF /GC0 /GC1
  280.   /GC2 /GC3 /GC4 /GC5 /GC6 /GC7 /GC8 /GC9 /GCA /GCB /GCC /GCD /GCE /GCF /GD0
  281.   /GD1 /GD2 /GD3 /GD4 /GD5 /GD6 /GD7 /GD8 /GD9 /GDA /GDB /GDC /GDD /GDE /GDF
  282.   /GE0 /GE1 /GE2 /GE3 /GE4 /GE5 /GE6 /GE7 /GE8 /GE9 /GEA /GEB /GEC /GED /GEE
  283.   /GEF /GF0 /GF1 /GF2 /GF3 /GF4 /GF5 /GF6 /GF7 /GF8 /GF9 /GFA /GFB /GFC /GFD
  284.   % 1050
  285.   /GFE /GFF 
  286.   % 1052
  287.   ] def
  288.  
  289. /oldDviGlyphs [
  290.   % More self-named glyphs for old dvitops type 3 fonts ...
  291.   % 1052
  292.   0 1 127 { 10 3 string cvrs cvn } for
  293.   % 1180
  294.   ] def
  295.  
  296. /StandardGlyphs //TimesRomanGlyphs length 896 add array def
  297. //StandardGlyphs 0 //TimesRomanGlyphs putinterval
  298. //StandardGlyphs //TimesRomanGlyphs length //dvipsGlyphs putinterval
  299. //StandardGlyphs //TimesRomanGlyphs length 256 add //ttypeGlyphs1 putinterval
  300. //StandardGlyphs //TimesRomanGlyphs length 512 add //ttypeGlyphs2 putinterval
  301. //StandardGlyphs //TimesRomanGlyphs length 768 add //oldDviGlyphs putinterval
  302.  
  303. /standardMap StandardGlyphs length dict
  304.   % Maps names to indices in StandardGlyphs.
  305.   0 StandardGlyphs {
  306.     2 index exch
  307.     2 copy known { pop pop } { 2 index put } ifelse
  308.     1 add
  309.     } forall
  310.   pop def
  311.  
  312. /printInt {                  % stack: n
  313.   % Prints an integer followed by a space on stdout
  314.   //tempString cvs print ( ) print
  315.   } bind def
  316.  
  317. /showxy {                    %stack:  x y
  318.   % prints a pair of integers on stdout, converting to 1/100th's
  319.   exch
  320.   100 mul round cvi //printInt exec
  321.   100 mul round cvi //printInt exec
  322.   } bind def
  323.  
  324. /characterToReporting {              % stack: x y -> x' y'
  325.   % Transforms a vector in currentfont's character coordinate
  326.   % system to the reporting coordinate system
  327.   currentfont /FontMatrix get
  328.   dtransform                 % to current user coordinates
  329.   dtransform                 % to device coordinates
  330.   //reportMatrix idtransform % to reporting coordinates
  331.   } def
  332.  
  333. /printCharacterOrigin {
  334.   % Prints the position in the reporting coordinate system at which a
  335.   % character origin would be painted using currentfont
  336.   0 0 currentfont /FontMatrix get transform
  337.   currentpoint exch 4 -1 roll add 3 1 roll add
  338.   transform //reportMatrix itransform
  339.   //showxy exec
  340.   } bind def
  341.  
  342. /printMap {
  343.   % Print map from indices in currentfont/Encoding to StandardEncoding indices
  344.   16 currentfont /Encoding get dup length //printInt exec {
  345.     exch dup 16 eq { () = pop 1 } { 1 add } ifelse exch
  346.     //standardMap exch
  347.     2 copy known {
  348.       get //printInt exec
  349.       } {
  350.       pop pop (9999 ) print
  351.       } ifelse
  352.     } forall
  353.   pop () =
  354.   } bind def
  355.  
  356. /metricsString (X) def
  357.  
  358. /printMetrics {
  359.   % Print bounding box and character metrics for currentfont
  360.   % Sadly, dvitops produces illegal type 3 fonts with no /.notdef entry. The
  361.   % use of "stopped" deals with that and any other silliness.
  362.   currentfont /FontBBox get aload pop 4 2 roll
  363.   //showxy exec
  364.   //showxy exec
  365.   currentfont /FontMatrix get
  366.   currentfont /FontType get 3 eq {
  367.     //privateDict /pm.dictCount countdictstack put
  368.     count //privateDict exch /pm.count exch put
  369.     //privateDict /pm.save save put
  370.     0 1 255 {
  371.       dup 8 mod 0 eq { () = } if
  372.       //metricsString exch 0 exch put
  373.       { //metricsString //stringwidth exec
  374.         2 index idtransform          % to font's character coordinates
  375.         } stopped {
  376.         count //privateDict /pm.count get sub { pop } repeat
  377.         countdictstack //privateDict /pm.dictCount get sub { end } repeat
  378.         //privateDict /pm.save get restore
  379.         //privateDict /pm.save save put
  380.         0 0
  381.         } if
  382.       //showxy exec
  383.       } for
  384.     //privateDict /pm.save get restore % necessary to balance the "save"
  385.     }{
  386.     currentfont /CharStrings get
  387.     currentfont /Encoding get
  388.     0 1 255 {
  389.       dup 8 mod 0 eq { () = } if
  390.       2 copy get 3 index exch known {
  391.         //metricsString exch 0 exch put
  392.         //metricsString //stringwidth exec
  393.         4 index idtransform          % to font's character coordinates
  394.         } {
  395.         pop 0 0
  396.         } ifelse
  397.       //showxy exec
  398.       } for
  399.       pop pop                                % encoding, charstrings
  400.     } ifelse
  401.   pop                                % fontmatrix
  402.   } bind def
  403.  
  404.  
  405. %
  406. % The main work: reportMetrics, reportEncoding, reportFont and report
  407. %
  408.  
  409. /reportMetrics {             % stack: -> m
  410.                              % privateDict is open
  411.   % Print new "m" directive for currentfont
  412.   (QM ) print
  413.   lastMetrics 1 add /lastMetrics 1 index def
  414.   dup //printInt exec
  415.   //printMetrics exec
  416.   () =
  417.   } bind def
  418.  
  419. /reportEncoding {            % stack: -> e
  420.                              % privateDict is open
  421.   % Print new "e" directive for currentfont
  422.   (QE ) print
  423.   lastEncoding 1 add /lastEncoding 1 index def
  424.   dup //printInt exec
  425.   //printMap exec
  426.   } bind def
  427.  
  428. /spaceString (X) def         % for space char from current encoding
  429.  
  430. /reportFont {                        % stack: any -> unchanged
  431.   % Report currentfont to the user and record its number
  432.   % //privateDict is open
  433.   % Sets //privateDict/spaceString to font's encoding's space string, if any,
  434.   % and sets //privateDict/hasSpace to indicate whether there's a space char.
  435.   currentfont /UniqueID known not {
  436.     //reportMetrics exec
  437.     } {
  438.     //metrics currentfont /UniqueID get
  439.     2 copy known {
  440.       get
  441.       } {
  442.       //reportMetrics exec
  443.       dup 4 1 roll put               % define in /metrics
  444.       } ifelse
  445.     } ifelse                 % stack: m
  446.   //encodings currentfont /Encoding get
  447.   2 copy known {
  448.     get
  449.     } {
  450.     //reportEncoding exec    % leaves e on stack
  451.     dup 4 1 roll put         % define in /encodings
  452.     % Find space character number for the encoding.
  453.     % Biased towards number 32, so avoid problems with weird encodings
  454.     //encodingSpace 1 index  % dict and key for putting the result
  455.     currentfont /Encoding get
  456.     dup length 32 le {
  457.       false
  458.       } {
  459.       dup 32 get dup /space eq exch /G20 eq or
  460.       } ifelse {
  461.       pop 32
  462.       } {
  463.       % It's not character number 32: search from 0
  464.       0 exch {
  465.         dup /space eq exch dup /G20 eq exch /suppress eq or or { exit } if
  466.         1 add
  467.         } forall
  468.       } ifelse
  469.     put                              % put in /encodingSpace
  470.     } ifelse                 % stack: m e
  471.   //encodingSpace 1 index get        % font's space character (256 if none)
  472.   /hasSpace 1 index 256 lt def
  473.   hasSpace { //spaceString exch 0 exch put } { pop } ifelse
  474.   (QF ) print
  475.   lastFontNum 1 add /lastFontNum 1 index def
  476.   //fonts currentfont 2 index put % record fontNum in /fonts
  477.   dup //printInt exec                % print fontNum
  478.                              % stack: m e f
  479.   1000 0 //characterToReporting exec 2 copy //showxy exec
  480.   0 1000 //characterToReporting exec 2 copy //showxy exec
  481.   4 array astore             % stack: m e f array
  482.   //fontsUnit 3 1 roll put   % stack: m e
  483.   //printInt exec            % print encoding number
  484.   //printInt exec            % print metrics number
  485.   () =
  486.   } bind def
  487.  
  488. /reportFontCreation {                % stack: font
  489.   % Report a newly created font. Called now so that if later uses are
  490.   % inside a save/restore we don't forget it.
  491.   % NOTE: this is currently not used, since it actually slows things down
  492.   //privateDict begin
  493.   inUse not {
  494.     /inUse true def
  495.     dup currentfont exch setfont //reportFont exec setfont
  496.     /inUse false def
  497.     } if
  498.   end
  499.   } bind def
  500.  
  501. /reportSubString {           % stack: args string -> args
  502.   % Report the rendering of a string, assumed to be a single word.
  503.   % privateDict is open.  /n is font number, /p is call-back
  504.   dup length 0 eq {
  505.     p
  506.     } {
  507.     (QS ) print
  508.     n //printInt exec
  509.     //printCharacterOrigin exec
  510.     dup length //printInt exec
  511.     dup print ( ) print
  512.     /p load end                      % close privateDict during the call-back
  513.     exec                     % render the string; leaves args on stack
  514.     //privateDict begin
  515.     //printCharacterOrigin exec
  516.     () =
  517.     } ifelse
  518.   } bind def
  519.  
  520. /report {                    % stack: args string proc -> args
  521.   % Report the rendering of a string.
  522.   % Calls proc for each word and space.  The call-back should expect "args"
  523.   % on the stack followed by a string, and should leave "args" on the stack.
  524.   //privateDict begin
  525.   inUse {
  526.     end exec
  527.     } {
  528.     /inUse true def
  529.     //fonts currentfont
  530.     2 copy known not { //reportFont exec } if
  531.     get                              % stack: probable font-number
  532.     % check if points transform as before ...
  533.     //fontsUnit 1 index get
  534.     1000 0 //characterToReporting exec
  535.     0 1000 //characterToReporting exec
  536.     4 index 3 get ne 4 1 roll
  537.     4 index 2 get ne 4 1 roll
  538.     4 index 1 get ne 4 1 roll
  539.     4 index 0 get ne 5 -1 roll pop
  540.     or or or {                       % if transformed points differ
  541.       //reportFont exec
  542.       pop //fonts currentfont get
  543.       } if                   % stack: args string proc n
  544.     /n exch def
  545.     /p exch def              % stack: args string
  546.     hasSpace {
  547.       {                      % begin loop
  548.         //spaceString search {
  549.           exch pop exch /s exch def
  550.           //reportSubString exec
  551.           //spaceString p
  552.           s
  553.           } {
  554.           //reportSubString exec
  555.           exit
  556.           } ifelse
  557.         } loop
  558.       } {
  559.       //reportSubString exec
  560.       } ifelse
  561.     /inUse false def
  562.     end
  563.     } ifelse
  564.   } bind def
  565.  
  566. /dontReport {                        % stack: proc
  567.   % Call "proc" with //privateDict/inUse set to true
  568.   //privateDict /inUse get {
  569.     exec
  570.     } {
  571.     //privateDict /inUse true put
  572.     exec
  573.     //privateDict /inUse false put
  574.     } ifelse
  575.   } bind def
  576.  
  577. /kshow.temp (X) def          % scratch space for kshow
  578.  
  579. % Output inverse of initial currentmatrix, for possible use by postprocessor.
  580. (QI ) print
  581. matrix currentmatrix matrix invertmatrix
  582. { 100 mul round cvi //printInt exec } forall
  583. () =
  584.  
  585. userdict begin                       % subsequent definitions are publicly visible
  586.  
  587. % Objects placed in systemdict must be in global memory,
  588. % and must not reference local objects.
  589. /setglobal where
  590.  { pop currentglobal true setglobal }
  591.  { }
  592. ifelse
  593.  
  594.  
  595. %
  596. % Redefine the character rendering operations to call "report"
  597. %
  598.  
  599. /show { { show }
  600.   //systemdict /pstotextLocalDict get /report get
  601.   exec } bind redef
  602.  
  603. /ashow { {3 copy ashow pop}
  604.   //systemdict /pstotextLocalDict get /report get
  605.   exec pop pop } bind redef
  606.  
  607. /widthshow { {4 copy widthshow pop}
  608.   //systemdict /pstotextLocalDict get /report get
  609.   exec pop pop pop } bind redef
  610.  
  611. /awidthshow { {6 copy awidthshow pop}
  612.   //systemdict /pstotextLocalDict get /report get 
  613.   exec 5 {pop} repeat } bind redef
  614.  
  615. /kshow {                     % stack: proc string
  616.   exch //systemdict /pstotextLocalDict get exch /kshow.proc exch put
  617.   false exch                 % stack: false string
  618.   {                          % stack: false next | prev true next
  619.     //systemdict /pstotextLocaldict get /kshow.temp get 0 2 index put
  620.     exch { //systemdict /pstotextLocalDict get
  621.            /kshow.proc get exec
  622.          } { pop } ifelse
  623.     //systemdict /pstotextLocaldict get
  624.     /kshow.temp get //show exec
  625.     //systemdict /pstotextLocaldict get
  626.     /kshow.temp get 0 get true       % stack: this true
  627.     } forall
  628.                              % stack: false | last true
  629.   { pop } if
  630.   } bind redef
  631.  
  632.  
  633. %
  634. % Redefine non-rendering operations so that they don't report
  635. %
  636.  
  637. /stringwidth { {stringwidth}
  638.   //systemdict /pstotextLocalDict get /dontReport get
  639.   exec } bind redef
  640.  
  641. /charpath { {charpath}
  642.   //systemdict /pstotextLocalDict get /dontReport get
  643.   exec } bind redef
  644.  
  645.  
  646. %
  647. % Intercept and report the page operations
  648. %
  649.  
  650. /copypage { (QC) = flush copypage } bind redef
  651.  
  652. /erasepage { (QZ) = flush erasepage } bind redef
  653.  
  654. /showpage { (QP) = flush showpage } bind redef
  655.  
  656.  
  657. %
  658. % Intercept font creation so as to record the font inside less save/restore's
  659. % NOTE: disabled, because it actually slows things down
  660. %
  661.  
  662. % /definefont { definefont //reportFontCreation exec } bind redef
  663.  
  664. % /makefont { makefont //reportFontCreation exec } bind redef
  665.  
  666. % /scalefont { scalefont //reportFontCreation exec } bind redef
  667.  
  668. %
  669. % Clean-up
  670. %
  671.  
  672. % restore local/global state
  673. /setglobal where
  674.  { pop setglobal }
  675.  { }
  676. ifelse
  677.  
  678. end                          % close nested userdict begin
  679. end                          % close private dictionary
  680.  
  681. % Bind the operators we just defined, and all the others if we didn't
  682. % do it before.  Also reenable 'bind' for future files.
  683.  
  684. revision 353 ge {
  685. .bindoperators
  686. NOBIND currentdict systemdict ne and
  687.  { systemdict begin .bindoperators end }
  688. if
  689. /DELAYBIND where { pop DELAYBIND { .bindnow } if } if
  690. } if
  691.  
  692. systemdict readonly pop
  693. % Restore the current local/global VM mode.
  694. % exec
  695.  
  696.  
  697. %
  698. % Testing
  699. %
  700.  
  701. false {
  702.   100 dict begin
  703.   (Times 12, two strings; second one sloping up with ashow:)=
  704.   /Times-Roman findfont 12 scalefont dup /t12 exch def setfont
  705.   72 300 moveto (Hello world) show
  706.   72 280 moveto 10 1 (Hello world once more) ashow
  707.   (Times 10 two strings:)=
  708.   /Times-Roman findfont 10 scalefont setfont
  709.   72 260 moveto (Third) show
  710.   72 240 moveto (Fourth) show
  711.   (Symbol 12, one string:)=
  712.   /Symbol findfont 12 scalefont setfont
  713.   72 220 moveto (symbol string) show
  714.   (Helvetica 12, two strings:)=
  715.   /Helvetica findfont 12 scalefont setfont
  716.   72 200 moveto (Fifth) show
  717.   72 180 moveto (Sixth) show
  718.   (Times 12 again, two strings; second one with kshow:)=
  719.   t12 setfont
  720.   72 160 moveto (Seventh) show
  721.   end
  722.   72 140 moveto
  723.   gsave
  724.     /dx 1.0 def
  725.     { pop pop
  726.       dx 1 add /dx 1 index def
  727.       0 rmoveto } (Accelerated letter spacing) kshow
  728.     grestore
  729.   (Times 12 scaled by 2:)=
  730.   72 100 moveto
  731.   gsave
  732.     2 2 scale
  733.     (Ninth) show
  734.     grestore
  735.   count 0 ne { (Left on stack:)= pstack } if
  736.   flush
  737.   } if